home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 235 / Issue 235 - September 2007 - DPCS0907DVD.ISO / Microsoft / Expression Blend / Blend.en.msi / Microsoft.Expression.InteractiveDesigner.Help.en / search.js < prev    next >
Encoding:
JavaScript  |  2007-03-23  |  16.7 KB  |  452 lines

  1. //*==============================================================================
  2. //*    ** DO NOT REMOVE OR MODIFY THIS COPYRIGHT MESSAGE **
  3. //*
  4. //*    Helpware Search 1.0
  5. //*    Copyright (c) 2004-2005 The Helpware Group
  6. //*    http://helpware.net/FAR/
  7. //*    Requires a Modern Browser that supports JavaScript such as IE4
  8. //*    WARNING: You must purchase a copy of FAR HTML v4 or greater to use this file.
  9. //*
  10. //*==============================================================================
  11. //*  31-May-2005: RWC001 - Fixed Offby one error in highlighting. First word would not highlight. 
  12. //*
  13. //*
  14. //*
  15. //*
  16.  
  17.  
  18. //var SearchFiles = ["index.htm","Search_OzNet.html"...
  19. //var SearchTitles =["Molecular products","OzNet Web"...
  20. //var SearchIndexes = [["0-0",[128,129,256,257,323]]...
  21. // ...,["WATER;",[355,361]],["WATER-CIRCULATOR",[383]],...
  22.  
  23.  
  24. //Options
  25. var PARAM_PartialMatchOK = true;
  26. var PARAM_TargetWindow = 'content';
  27.  
  28. //Globals - SearchResults is an array of Page Indexes
  29. var SearchResults = [];
  30. var gFindList = [];
  31. var gFirstFindCall = true;
  32.  
  33.  
  34. //------------------------------------------------------------------------------
  35. // Get Operator Type
  36. //   text should be Uppercase. Return 0 = normal search text
  37. //------------------------------------------------------------------------------
  38. var OPT_AND = 1;
  39. var OPT_OR  = 2;
  40. var OPT_NOT = 3;
  41. function xxGetOpType(text) {
  42.   if ((text=="NOT")||(text=="!")) return OPT_NOT;
  43.   else if ((text=="AND")||(text== "&")||(text== "+")) return OPT_AND;
  44.   else if ((text=="OR")||(text== "|")) return OPT_OR;
  45.   else return(0);
  46.   }
  47.  
  48.  
  49. //----------------------------------------------------------------------------
  50. // ProcessSearchTerms()
  51. //----------------------------------------------------------------------------
  52. // Params
  53. //   ss -- string of terms to parse and find
  54. //   DefaultOp - Search Operator to default to for each list term (OPT_OR, OPT_AND, OPT_NOT)
  55. // Desc
  56. //   Parse ss string --> String list. Default Return.
  57. //   Items forced Uppercase (since Database and all calls use uppercase for speed)
  58. //   User can insert override 'AND', 'OR', 'NOT' into the list of terms to
  59. //   alter how the next item is searched. After that we go back to Defaultop.
  60. // Optimization
  61. //   Pass in SearchIndexes + SearchResults arrays (by ref) so no global lookups - speed up loops
  62. //----------------------------------------------------------------------------
  63. function ProcessSearchTerms(ss, DefaultOp) {
  64.   //Parse string into array
  65.   var items = ss.split(" ");
  66.  
  67.   //----------------------------------------
  68.   // Remove empty list entried due to multiple spaces passed to split()
  69.   // Force all items to Uppercase
  70.   //----------------------------------------
  71.   var c = 0;
  72.   for (var i = 0; i < items.length; i++)
  73.     if (items[i] != "") { items[c] = items[i].toUpperCase(); c++; }
  74.   items.length = c;
  75.  
  76.   var CheckOp = true;
  77.   var otype = DefaultOp;
  78.   for (var i = 0; i < items.length; i++) {
  79.  
  80.     //----------------------------------------
  81.     // Check for Override Operators.
  82.     // Don't allow Op override if working with NOT terms
  83.     //----------------------------------------
  84.     if ((CheckOp) && (DefaultOp != OPT_NOT)) {
  85.       otype = xxGetOpType(items[i]);
  86.       CheckOp = (otype == 0);
  87.       if (CheckOp) otype = DefaultOp;
  88.       else continue;
  89.     }
  90.     CheckOp = true;
  91.  
  92.     //----------------------------------------
  93.     // Find Text results ==> SearchResults
  94.     //----------------------------------------
  95.     if (otype==OPT_OR)  FindText_OR(items[i], SearchIndexes, SearchResults);
  96.     if (otype==OPT_AND) FindText_AND(items[i], SearchIndexes, SearchResults);
  97.     if (otype==OPT_NOT) FindText_DEL(items[i], SearchIndexes, SearchResults);
  98.  
  99.     //build list of find words
  100.     if (DefaultOp!=OPT_NOT)
  101.       gFindList[gFindList.length] = items[i];
  102.  
  103.     //Clear global flag
  104.     gFirstFindCall = false;
  105.   }
  106. }
  107.  
  108. //------------------------------------------------------------------------------
  109. // s1 - Any words (OR) -->> one or more words present in a document is a result. Ie. Get the OR of all word search results.
  110. // s2 - All words (AND) -->> all words must be present in each result document. Ie. Get the AND of all word search results.
  111. // s3 - Not these words (NOT) -->> Only makes sense when used with the above. Knock out Topics containing these words.
  112. // b4 - Partial Word matching is ok - otherwise we match exaclty what is entered
  113. // s5 - target window -- default = 'content'
  114. // ----------------------------------------------
  115. // -- To match similar spellings in a full-text search, select the Match similar words check box.
  116. //    eg  "add", "adds", and "added".
  117. // -- To search for words in document titles only, select the Search titles only check box.
  118. // -- To highlight words in searched topics
  119. //------------------------------------------------------------------------------
  120. //  Notes
  121. //  - DoSearch(s1, s2, s3. partial)
  122. //     S1 is a string of words separated by spaces. Words are OR'd together
  123. //     S2 is a string of words separated by spaces. Words are AND'd together
  124. //     S3 is a string of words separated by spaces. Words are Deleted from other results
  125. //  - User can override default properties of S1 and S2 by using the following keywords
  126. //    "OR","|" the next word is OR'd
  127. //    "AND","&","+" the next word is AND'd
  128. //    "NOT","!" the next word is removed
  129. //
  130. //------------------------------------------------------------------------------
  131. function DoSearch(s1, s2, s3, b4, s5)
  132. {
  133.   //----------------------------------------------------------------------------
  134.   // Init
  135.   //   - Reset First AND call flag. The first time must be an OR.
  136.   //   - Clear SearchResults list
  137.   //   - Clear target list control
  138.   //----------------------------------------------------------------------------
  139.   gFirstFindCall = true;
  140.   SearchResults.length = 0;
  141.   gFindList.length = 0;
  142.   if (document.forms['searchform'].SearchResultList)
  143.     document.forms['searchform'].SearchResultList.length = 0;
  144.   PARAM_PartialMatchOK = b4;
  145.   if (s5 == '') PARAM_TargetWindow = 'content';
  146.     else PARAM_TargetWindow = s5;
  147.  
  148.   //----------------------------------------------------------------------------
  149.   //1. (OR) Find documents with "Any of these Words"  ==> SearchResults
  150.   //2. (AND) Find documents with "All these Words"  ==> SearchResults
  151.   //3. (NOT) SearchResults must NOT files containing these words ==> Remove from SearchResults
  152.   //----------------------------------------------------------------------------
  153.   ProcessSearchTerms(s1, OPT_OR);
  154.   ProcessSearchTerms(s2, OPT_AND);
  155.   ProcessSearchTerms(s3, OPT_NOT);
  156.   
  157.   //----------------------------------------------------------------------------
  158.   // Display SearchResults
  159.   //----------------------------------------------------------------------------
  160.   if (SearchResults.length == 0) {
  161.     alert("No matches found!");
  162.     return(0); }
  163.  
  164.   //Search Results list exists  
  165.   if (document.forms['searchform'].SearchResultList)
  166.   {
  167.     //Fill SearchResults List -- 500 item limit same as H1.x and H2.x
  168.     for(var i=0;((i<SearchResults.length) && (i<500));i++) {
  169.       var new_option = document.createElement('option');
  170.       new_option.text = SearchTitles[SearchResults[i]];
  171.       new_option.value = SearchFiles[SearchResults[i]];
  172.       document.forms['searchform'].SearchResultList[i]=new_option;
  173.     }
  174.  
  175.     //open the first file
  176. //    OpenResultListDoc();
  177.  
  178.   }
  179.   else {
  180.     ShowSearchResultsWindow();
  181.   }
  182.  
  183.   return(SearchResults.length);
  184.  
  185. }
  186.  
  187.  
  188.  
  189. //----------------------------------------------------------------------------
  190. // OR -- Add only Unique items to the SearchResults Array
  191. //   items - array of Idxs to OR into SearchResults
  192. //   SearchResults - Pass in by ref to to optomize global scope access
  193. //----------------------------------------------------------------------------
  194. function OR_WithSearchResults(items, SearchResults) {
  195.   var found;
  196.   for (var i = 0; i < items.length; i++) {
  197.  
  198.     //Already in list?
  199.     found = false;
  200.     for (var k = 0; (k < SearchResults.length) && (!found); k++)
  201.       if (items[i] == SearchResults[k])
  202.         found = true;
  203.  
  204.     //Not in list? Then Add it!
  205.     if (!found)
  206.       SearchResults[SearchResults.length] = items[i];
  207.   }
  208. }
  209.  
  210. //----------------------------------------------------------------------------
  211. // AND -- Keep only the intersection of items and SearchResults
  212. //   items - array of Idxs to AND into SearchResults
  213. //   SearchResults - Pass in by ref to to optomize global scope access
  214. //----------------------------------------------------------------------------
  215. function AND_WithSearchResults(items, SearchResults) {
  216.   var count = 0;
  217.   for (var i = 0; i < SearchResults.length; i++)
  218.     for (var k = 0; k < items.length; k++) {
  219.       if (items[k] == SearchResults[i]) {
  220.         SearchResults[count] = SearchResults[i];
  221.         count++;
  222.         break;
  223.       }
  224.     }
  225.   SearchResults.length = count;
  226. }
  227.  
  228. //----------------------------------------------------------------------------
  229. // DEL -- Remove items from SearchResults list
  230. //   items - array of Idxs to DEL from SearchResults
  231. //   SearchResults - Pass in by ref to to optomize global scope access
  232. //----------------------------------------------------------------------------
  233. function DEL_WithSearchResults(items, SearchResults) {
  234.   var count = 0;
  235.   var found; 
  236.   for (var i = 0; i < SearchResults.length; i++) {
  237.  
  238.     //Its Delete Item in the Result list?
  239.     found = false;
  240.     for (var k = 0; (k < items.length) && (!found); k++)
  241.       if (items[k] == SearchResults[i]) {
  242.         found = true;
  243.         break;
  244.       }
  245.  
  246.     //Not Found in delete list? then keep Result
  247.     if (!found) {
  248.       SearchResults[count] = SearchResults[i];
  249.       count++;
  250.       }
  251.   }
  252.   SearchResults.length = count;
  253. }
  254.  
  255.  
  256. //----------------------------------------------------------------------------
  257. // Find Database Text
  258. // By this stage all strings are Uppercase
  259. // Optimization
  260. //   - String Compare - check length the same, and check first char match before
  261. //     going on to actually do a string compare.
  262. //   - Pass Global SearchIndexes in instead of accessing out of scope many times
  263. //----------------------------------------------------------------------------
  264.  
  265. //Find Text (in SearchIndex passed in by ref) and OR matches into SearchResults list
  266. function FindText_OR(SrchText, SearchIndexes, SearchResults)
  267. {
  268.   if (PARAM_PartialMatchOK) {
  269.     for(var i=0;i<SearchIndexes.length;i++)
  270.       if((SearchIndexes[i][0].length >= SrchText.length)
  271.       && (SearchIndexes[i][0].indexOf(SrchText) >= 0)) {
  272.         OR_WithSearchResults(SearchIndexes[i][1], SearchResults);
  273.       }
  274.   }
  275.   else {
  276.     //Not Partial - Fast - Find exact match and break out  
  277.     for(var i=0;i<SearchIndexes.length;i++)
  278.       if((SearchIndexes[i][0].length == SrchText.length)
  279.       && (SearchIndexes[i][0] == SrchText)) {
  280.         OR_WithSearchResults(SearchIndexes[i][1], SearchResults);
  281.         break;
  282.       }
  283.   }
  284. }
  285.  
  286. //Find Text (in SearchIndex passed in by ref) and AND matches into SearchResults list
  287. function FindText_AND(SrchText, SearchIndexes, SearchResults)
  288. {
  289.   //Optimization: Take copy to minimize global out of scope lookups
  290.   var FirstFindCall = gFirstFindCall;
  291.  
  292.   //If 2nd or 3rd... item and No SearchResults then Nothing to AND with
  293.   if ((!FirstFindCall) && (SearchResults.length == 0))
  294.     return;
  295.  
  296.   var tempList = [];
  297.   if (PARAM_PartialMatchOK) {
  298.     for(var i=0;i<SearchIndexes.length;i++)
  299.       if((SearchIndexes[i][0].length >= SrchText.length)
  300.       && (SearchIndexes[i][0].indexOf(SrchText) >= 0))
  301.         OR_WithSearchResults(SearchIndexes[i][1], tempList);
  302.   }
  303.   else {
  304.     //Not Partial - Fast - Find exact match and break out
  305.     for(var i=0;i<SearchIndexes.length;i++)
  306.       if((SearchIndexes[i][0].length == SrchText.length)
  307.       && (SearchIndexes[i][0] == SrchText)) {
  308.         OR_WithSearchResults(SearchIndexes[i][1], tempList);
  309.         //Exact match - we are done
  310.         break;
  311.       }
  312.   }
  313.  
  314.   //Add Results
  315.   //1st call wont have results yet -- We must OR into SearchResults as AND would not do nothing
  316.   if (tempList.length >= 0) {
  317.     if (FirstFindCall)
  318.       OR_WithSearchResults(tempList, SearchResults);
  319.     else
  320.       AND_WithSearchResults(tempList, SearchResults);
  321.   }
  322.   else
  323.     //No Results + not first call -- AND will wipe out all results
  324.     if (!FirstFindCall)
  325.       SearchResults.length = 0;
  326. }
  327.  
  328.  
  329. //Find Text (in SearchIndex passed in by ref) and DELETE matches from SearchResults list
  330. function FindText_DEL(SrchText, SearchIndexes, SearchResults)
  331. {
  332.   //first check there is something to delete from
  333.   if (SearchResults.length)
  334.     for(var i=0;i<SearchIndexes.length;i++)
  335.       if((SearchIndexes[i][0].length == SrchText.length)
  336.       &&(SearchIndexes[i][0]==SrchText)) {
  337.  
  338.         //Send match words idx array off to be deleted from SearchResults
  339.         DEL_WithSearchResults(SearchIndexes[i][1], SearchResults);
  340.  
  341.         //We found the word and its idx array data -- Jobs done
  342.         break;
  343.       }
  344. }
  345.  
  346.  
  347.  
  348. //------------------------------------------------------------------------------
  349. // Highlighting
  350. //------------------------------------------------------------------------------
  351.  
  352. var targetWin = null;
  353. var HilightColorStr = 'background-color:#FFFFAA;color:#222222;';
  354.  
  355.  
  356. function checkPage() {
  357.   //Not all browser support 'readystate'
  358.   if ((targetWin.document.readyState != undefined) && (targetWin.document.readyState != 'complete')) {
  359.     setTimeout('checkPage()',100);   //try again later
  360.   }
  361.   else if (document.all)  //IE Browser
  362.   {
  363.     var xBody = targetWin.document.body;
  364.     for(var k = 0; k < gFindList.length; k++)
  365.     {
  366.       var t = xBody.createTextRange();
  367.       if (t!=null)
  368.       {
  369.         for(var i=0; i<100; i++) {
  370.           //Select next word in doc
  371.           t.moveStart("word", 0);      //RWC001: fix: was 1 missing the first word
  372.           if (t.findText(gFindList[k]))
  373.             t.pasteHTML("<span style='"+HilightColorStr+"'>" + t.text + "</span>");
  374.           else
  375.             break;
  376.         }
  377.       }
  378.     }
  379.   }
  380.   else // Opera, Mozilla browsers (Mozilla Suite, Firefox, Netscape 6/7) etc
  381.   {
  382.     //ToDo: Search highlighting in Mozilla is more complicated  
  383.   }
  384. }
  385.  
  386.  
  387. //------------------------------------------------------------------------------
  388. // Open List item in Browser - Target = PARAM_TargetWindow
  389. //------------------------------------------------------------------------------
  390. function OpenResultListDoc() {
  391.   var iSelect = document.forms['searchform'].SearchResultList.selectedIndex;
  392.   if (iSelect < 0) iSelect = 0;
  393.  
  394.   if (window.navigator.userAgent.indexOf("Netscape") > 0) {
  395.     top.right.location.href = document.forms['searchform'].SearchResultList.options[iSelect].value;
  396.     targetWin = top.right.window;
  397.   }
  398.   else //all other browsers
  399.     targetWin = open(document.forms['searchform'].SearchResultList.options[iSelect].value, "_self");
  400.     
  401.   //Highlight
  402.   if (targetWin)
  403.     setTimeout('checkPage()',100);
  404. }
  405.  
  406.  
  407. //------------------------------------------------------------------------------
  408. // Search Results Window -- called if user does not
  409. //  -- 500 item limit same as H1.x and H2.x
  410. //------------------------------------------------------------------------------
  411. function ShowSearchResultsWindow() {
  412.   var newWindow = window.open("about:blank", "searchValue", "width=500, height=300, resizable=yes, maximizable=no, status=yes, scrollbars=yes");
  413.   newWindow.document.write('<html>\n<head>\n<title>Search Results</title>\n');
  414.   newWindow.document.write('</head>\n');
  415.   newWindow.document.write('<body>\n');
  416.  
  417.   //Fill SearchResults List
  418.   for(var i=0;((i<SearchResults.length) && (i<500));i++) {
  419.     //Search Topic Title
  420.     var aTitle = SearchTitles[SearchResults[i]];
  421.     //URL
  422.     var aURL = SearchFiles[SearchResults[i]];
  423.  
  424.     newWindow.document.write('<p>Title: '+ aTitle +'<br>\n');
  425.     newWindow.document.write('URL: <a href="'+ aURL +'">'+aURL+'</a></p>\n');
  426.   }
  427.  
  428.   newWindow.document.write("</body>\n");
  429.   newWindow.document.write("</html>\n");
  430.   newWindow.document.close();
  431. //  self.name = "main";
  432. }
  433.  
  434. //------------------------------------------------------------------------------
  435. // Other Script
  436. //------------------------------------------------------------------------------
  437. function CloseNavPane() {
  438.   if ((top.content.location == null) || (top.content.location == undefined) || (typeof(top.content.location.href) != "string") || (top.content.location.href == ""))
  439.     top.location="index.htm";   //can't work out the current content file - return home
  440.   else
  441.     top.location=top.content.location;
  442. }
  443.  
  444.  
  445. //------------------------------------------------------------------------------
  446. //
  447. //------------------------------------------------------------------------------
  448.  
  449.  
  450.  
  451.  
  452.